import { _decorator, Component, Color, Node, UITransform, Vec2, AudioClip, Vec3, EventTouch, AudioSource, find, Prefab, instantiate, Label, resources, SpriteFrame, Sprite } from 'cc';
const { ccclass, property } = _decorator;
import { Player } from './Player';
import { Utils } from './Utils';

@ccclass('Backpack')
export class Backpack extends Component {
    @property({type: Prefab})
    backpackItemPrefab: Prefab = null

    @property({type: Node})
    backpackLayoutNode: Node = null

    @property({type: AudioClip})
    selectAudio: AudioClip = null!

    @property({type: AudioClip})
    clickAudio: AudioClip = null!

    backpackInfo: object = {}
    selectedBackpackItem: Node = null

    utils: Utils = null
    audioSource: AudioSource = null

    start() {
        this.initComponents()
        this.initTouchEvents()
    }

    /** 
     * @zh
     * 每次显示背包就从缓存中获取背包信息。
    */
    onEnable() {
        this.getBackpackInfoFromLocalStorage()
    }

    /** 
     * @zh
     * 初始化组件。
    */
    initComponents() {
        this.audioSource = find('Canvas').getComponent(AudioSource)
        this.utils = find('Canvas').getComponent(Utils)
    }

    /** 
     * @zh
     * 初始化触摸监听事件。
    */
    initTouchEvents() {
        this.backpackLayoutNode.on(Node.EventType.TOUCH_END, this.onTouchEnd, this)
    }

    /** 
     * @zh
     * 触摸开始时执行的逻辑，选中某一个物品。
    */
    onTouchEnd(event: EventTouch) {
        // 没有物品则直接返回
        if (!this.backpackLayoutNode.children.length) {
            return
        }

        // 根据触摸坐标选中背包物品
        let loc = event.getUILocation()
        let pos = this.backpackLayoutNode.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(loc.x, loc.y, 0))
    
        for (let i=0; i<this.backpackLayoutNode.children.length; i++) {
            let backpackItem = this.backpackLayoutNode.children[i]
            if (!backpackItem.getComponent(UITransform).getBoundingBox().contains(new Vec2(pos.x, pos.y))) {
                continue
            }

            // 将当前选中的的方框active设为true
            this.selectedBackpackItem = backpackItem
            this.audioSource.playOneShot(this.selectAudio)
            backpackItem.getChildByName('frame').active = true

            // 其余方框的设置为false
            for (let i=0; i<this.backpackLayoutNode.children.length; i++) {
                let item = this.backpackLayoutNode.children[i] 
                if (item != backpackItem) {
                    item.getChildByName('frame').active = false
                }   
            }

            break
        }
    }

    /** 
     * @zh
     * 生成背包物品预制。
    */
    spawnBackpackItem(name: string, num: number) {
        let backpackItem = instantiate(this.backpackItemPrefab)
        backpackItem.name = name
        backpackItem.getChildByName('label').getComponent(Label).string = num.toString()
        this.backpackLayoutNode.addChild(backpackItem)
        
        // 自定义物品需根据points信息设置各个像素点的颜色
        if (name.indexOf('customWeapon') > -1) {
            let points = this.backpackInfo[name]['points']
            let customWeaponNode = backpackItem.getChildByName('Custom Weapon')
            for (let i=0; i<points.length; i++) {
                let itemIndex = points[i][0]
                let colorHex = points[i][1]
                customWeaponNode.children[itemIndex].getComponent(Sprite).color = new Color().fromHEX(colorHex)
            }
        }

        // 非自定义物品直接设置spriteFrame
        else {
            resources.load(this.backpackInfo[name]['picPath'], SpriteFrame, (err: any, spriteFrame: SpriteFrame) => {
                backpackItem.getComponent(Sprite).spriteFrame = spriteFrame
            })
        }
    }

    /** 
     * @zh
     * 从缓存中获取背包信息。
    */
    getBackpackInfoFromLocalStorage() {
        if (!localStorage.getItem('lp-backpack')) {
            return
        }

        this.backpackLayoutNode.removeAllChildren()
        this.backpackInfo = JSON.parse(localStorage.getItem('lp-backpack'))
        for (let key in this.backpackInfo) {
            this.spawnBackpackItem(key, this.backpackInfo[key]['num'])
        }
    }

    /** 
     * @zh
     * 更新背包缓存信息。
    */
    updateBackpackInfo(addOrDel:string, itemKey: string, num: number, equipmentInfo: object=null) {
        // 添加
        if (addOrDel == 'ADD') {
            if (!this.backpackInfo[itemKey]) {
                this.backpackInfo[itemKey] = equipmentInfo
                this.backpackInfo[itemKey]['num'] = 0
            }

            this.backpackInfo[itemKey]['num'] += num
        }

        // 删除
        else {
            this.backpackInfo[itemKey]['num'] -= num
            this.selectedBackpackItem.getChildByName('label').getComponent(Label).string = this.backpackInfo[itemKey]['num'].toString()

            if (this.backpackInfo[itemKey]['num'] <= 0) {
                // 移除相应的装备信息
                delete this.backpackInfo[itemKey]

                // 移除相应的节点
                this.selectedBackpackItem.removeFromParent()
                this.selectedBackpackItem = null
            }
        }

        // 更新缓存
        localStorage.setItem('lp-backpack', JSON.stringify(this.backpackInfo))
    }

    /** 
     * @zh
     * 背包的使用按钮事件函数。
    */
    onBackpackEquipButtonClicked() {
        // 如果玩家没有选择任何物品，则按下使用按钮无效。
        if (!this.selectedBackpackItem) {
            return
        }

        // 从选中的物品中获取名称
        let itemKey = this.selectedBackpackItem.name 

        // 播放按钮点击音效
        this.audioSource.playOneShot(this.clickAudio)

        // 如果是武器
        if (this.backpackInfo[itemKey]['type'] == 'weapon') {
            this.utils.showFlashMessage(`已装备${this.backpackInfo[itemKey]['zh']}!`, 1)

            localStorage.setItem('lp-weapon', itemKey)

            // 清空自定义武器颜色
            let customWeaponNode = find('Canvas/Player/Weapon/Custom Weapon')
            for (let i =0; i<customWeaponNode.children.length; i++) {
                customWeaponNode.children[i].getComponent(Sprite).color = new Color(0, 0, 0, 0)
            }
            
            // 给主角装备武器
            let self = this
            resources.load(this.backpackInfo[itemKey]['picPath'], SpriteFrame, (err: any, spriteFrame: SpriteFrame) => {
                find('Canvas/Player/Weapon').getComponent(Sprite).spriteFrame = spriteFrame
                find('Canvas/Player').getComponent(Player).weaponInfo = self.backpackInfo[itemKey]
                this.updateBackpackInfo('DEL', itemKey, 1)
            })
        }

        // 如果是自定义武器
        else if (this.backpackInfo[itemKey]['type'] == 'customWeapon') {
            // 伤害值由AI评分决定          
            let damage = this.backpackInfo[itemKey]['damage']
            this.utils.showFlashMessage(`已装备自定义武器，攻击力为${damage}!`, 2)

            // 将武器节点图片删除
            let weaponNode = find('Canvas/Player/Weapon')
            weaponNode.getComponent(Sprite).spriteFrame = null

            // 将对应颜色添加到Custom Weapon节点上
            // 先将原来的颜色恢复
            let customWeaponNode = find('Canvas/Player/Weapon/Custom Weapon')
            for (let i =0; i<customWeaponNode.children.length; i++) {
                customWeaponNode.children[i].getComponent(Sprite).color = new Color(0, 0, 0, 0)
            }

            let points = this.backpackInfo[itemKey]['points']
            for (let i=0; i<points.length; i++) {
                let itemIndex = points[i][0]
                let colorHex = points[i][1]
                customWeaponNode.children[itemIndex].getComponent(Sprite).color = new Color().fromHEX(colorHex)
            }
            
            localStorage.setItem('lp-weapon', itemKey+'-'+damage.toString()+'-'+JSON.stringify(points))

            find('Canvas/Player').getComponent(Player).weaponInfo = this.backpackInfo[itemKey]

            // 更新拥有的制作图数量
            this.updateBackpackInfo('DEL', itemKey, 1)
        }

        // 如果是帽子防具
        else if (this.backpackInfo[itemKey]['type'] == 'hat') {
            this.utils.showFlashMessage(`已装备${this.backpackInfo[itemKey]['zh']}!`, 1)
            localStorage.setItem('lp-hat', itemKey)

            // 给主角装备帽子
            let self = this
            resources.load(this.backpackInfo[itemKey]['picPath'], SpriteFrame, (err: any, spriteFrame: SpriteFrame) => {
                find('Canvas/Player/Hat').getComponent(Sprite).spriteFrame = spriteFrame
                find('Canvas/Player').getComponent(Player).defense = 1
                find('Canvas/Player').getComponent(Player).defense += self.backpackInfo[itemKey]['defense']
                console.log(self.backpackInfo[itemKey]['defense'])
                this.updateBackpackInfo('DEL', itemKey, 1)
            })
        }

        // 如果是治疗药水
        else if (this.backpackInfo[itemKey]['type'] == 'cure') {
            find('Canvas/Player').getComponent(Player).recoverLife(this.backpackInfo[itemKey]['value'])
            this.utils.showFlashMessage(`已恢复${this.backpackInfo[itemKey]['value']}点血量!`, 1)
            this.updateBackpackInfo('DEL', itemKey, 1)
        }

        // 如果是技能
        else if (this.backpackInfo[itemKey]['type'] == 'skill') {
            // this.utils.showFlashMessage(`${this.backpackInfo[itemKey]['zh']}!!!`, 2)

            if (this.backpackInfo[itemKey]['en'] == 'lightBeam') {
                find('Canvas/Player').getComponent(Player).showLightBeamAttack()
            }
            else if (this.backpackInfo[itemKey]['en'] == 'fireball') {
                find('Canvas/Player').getComponent(Player).showFireballAttack()
            }
            else if (this.backpackInfo[itemKey]['en'] == 'lightning') {
                find('Canvas/Player').getComponent(Player).showLightningAttack()
            }
            else if (this.backpackInfo[itemKey]['en'] == 'trashBin') {
                find('Canvas/Player').getComponent(Player).showTrashBinAttack()
            }

            // 更新拥有的制作图数量
            this.updateBackpackInfo('DEL', itemKey, 1)
        }
    }
}


